__doc__ =   """ Functions for sophisticated selection of entities.
            """

from functools import partial
from operator import (gt, lt, ne, le, ge, eq, contains, or_)
from operator import itemgetter
from random import shuffle
from Einput import einput


def get_split(entities, level, *args, **kwargs):
    """ Returns Holders of split entities.
    """
    if args:
        attr = args[0]
    else:
        attr = kwargs['attr']
    ents = einput(entities, level)                      # get right holder
    clust_dicts = ents._split_children(*args, **kwargs) # split into dicts of ents
    clusters = []
    for (id_, clust) in clust_dicts.iteritems():
        cluster = einput(clust.values(), level, name="%s-%s" % (attr, id_))
        clusters.append(cluster)
    return clusters

def indicate(entity, selector, arranger, *args, **kwargs):
    """ Let's you select and sort ornamented children. Returns a list of entites.
    """
    # Use this function if you need to have both selected and sorted children,
    # otherwise look at MultiEntity methods.
    o__id_ents  = entity._ornament_children(*args, **kwargs)     # ornament
    o__id_ents_s = eval(selector)(o__id_ents)                    # select
    eval(arranger)(o__id_ents_s)                                 # arange
    ents = [ent for (o,(i,ent)) in o__id_ents_s]                 # de-ornament
    return ents

def selector(ornamented, value, operator):
    """ Select items from ornamented list. Return ornamented list.
    """
    selected = [o for o in ornamented if eval(operator)(value, o[0])]
    return selected
# provide default values for selector.
notnone = partial(selector, value =None, operator ='ne')
positive = partial(selector, value =0.0, operator ='lt')
zero = partial(selector, value =0.0, operator ='eq')

def arranger(ornamented, method, *args, **kwargs):
    """ Arrange elements in ornamented list.
    """
    try:
        getattr(ornamented, method)(*args, **kwargs)
    except AttributeError:
        eval(method)(ornamented, *args, **kwargs)
# provide default values for arranger.
min2max = partial(arranger, method ='sort', key =itemgetter(0))
max2min = partial(arranger, method ='sort', key =itemgetter(0), reverse =True)
shuffled = partial(arranger, method ='shuffle')



#EOF